﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Interactivity;
using nRoute.Components;
#if (WINRT)
using Windows.UI.Xaml;
using nRoute.Behaviors.Interactivity;
using Windows.UI.Xaml.Data;
#else
#endif

namespace nRoute.Behaviors.Triggers
{
    public class ReverseCommandTrigger
#if (WINRT)
        : TriggerBase<FrameworkElement>
#else
        : TriggerBase<DependencyObject>
#endif
    {
        public static readonly DependencyProperty ReverseCommandProperty =
            DependencyProperty.Register("ReverseCommand", typeof(Object), typeof(ReverseCommandTrigger),
            new PropertyMetadata(Utilities.Compatability.DP_UNSET_VALUE, new PropertyChangedCallback(OnCommandChanged)));

        private bool _isAttached;

#region Properties

        [Category("Common Properties")]
        [CustomPropertyValueEditor(CustomPropertyValueEditor.PropertyBinding)]
        public Object ReverseCommand
        {
            get { return (IReverseCommand)GetValue(ReverseCommandProperty); }
            set { SetValue(ReverseCommandProperty, value); }
        }

#if (WINRT)

        [Category("Common Properties")]
        [CustomPropertyValueEditor(CustomPropertyValueEditor.PropertyBinding)]
        public Binding ReverseCommandBinding
        {
            get { return GetBinding(ReverseCommandProperty); }
            set { SetBinding<Object>(ReverseCommandProperty, value); }
        }

#endif

#endregion

#region Handlers

        private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ReverseCommandTrigger)d).SetupHandlers(e.NewValue as IReverseCommand, e.OldValue as IReverseCommand);
        }

#endregion

#region Helpers

        protected override void OnAttached()
        {
            base.OnAttached();
            if (!_isAttached)
            {
                SetupHandlers(this.ReverseCommand as IReverseCommand, null);
            }
        }

        private void SetupHandlers(IReverseCommand newCommand, IReverseCommand oldCommand)
        {
            // we detach or attach
            if (oldCommand != null)
            {
                oldCommand.CommandExecuted -= Command_CommandExecuted;
                _isAttached = false;
            }

            if (newCommand != null)
            {
                newCommand.CommandExecuted += Command_CommandExecuted;
                _isAttached = true;
            }
        }

        private void Command_CommandExecuted(object sender, CommandEventArgs e)
        {
            if (this.AssociatedObject == null) return;      // this is to ensure with initial/static set properties the trigger isn't invoked

            // when the command is executed we execute the trigger
            // note_, we pass through the command parameter
            base.InvokeActions(e.CommandParameter);
        }

#endregion

    }
}
